/**
 * <one line to give the program's name and a brief idea of what it does.>
 * Copyright (C) Aug 2, 2011  Isaias
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package redclient.client;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import redclient.Items.Issue;
import redclient.Items.Project;
import redclient.RedmineCredentials;
import redclient.webclient.WebClient;
import redclient.webclient.WebClientException;

/**
 *
 * @author Isaias
 * @file RedManager.java
 */
public class RedManager {

    private static Map<RedmineCredentials, RedManager> instances;

    static{
        instances = new HashMap<RedmineCredentials, RedManager>();
    }

    private RedmineCredentials credentials;

    private boolean validSession = false;

    private WorkingMode workingMode;

    private WebClient webClient;



    private RedManager(RedmineCredentials credentials) throws WebClientException
    {
        this.credentials = credentials;
        webClient = new WebClient(credentials);
    }


    public static RedManager Connect(RedmineCredentials credentials) throws WebClientException
    {
        RedManager manager = null;
        if ( instances.containsKey(credentials) )
        {
            manager = instances.get(credentials);
        }
        else
        {
            manager = new RedManager(credentials);
            instances.put(credentials, manager);
        }
        return manager;
    }

    public List<Project> getProjects() throws WebClientException
    {
        List<Project> projects = null;
        projects = RedRestParser.parseProjects(webClient.getProjects(), credentials);

        List<Issue> issues = this.getIssues(credentials.getDateFormat());
        Runtime runtime = Runtime.getRuntime();
        System.out.printf("Free memory: %d, Total memory: %d, Max memory: %d\n", runtime.freeMemory(), runtime.totalMemory(), runtime.maxMemory());
        for(Project project : projects)
        {
            List<Issue> projectIssues = new Vector<Issue>();
            for( Issue issue : issues)
            {
                if ( issue.getProjectId().equals(project.getProjectId()))
                {
                    issue.setProject(project);
                    projectIssues.add(issue);
                }
            }
            project.setIssues(projectIssues);
        }
        return projects;
    }

    private List<Issue> getIssues(String dateFormat) throws WebClientException
    {
        List<Issue> issues = new Vector<Issue>();
        int page = 1;
        int parsed = 0;
        do
        {
            parsed = RedRestParser.parseIssues(webClient.getIssues(page++), issues, dateFormat);
        }
        while(parsed > 0);
        
        return issues;
    }


    /**
     * Invalidate the session forcing to create a new one
     */
    public void invalidateSession()
    {
        validSession = false;
    }

    /**
     * @return the validSession
     */
    public boolean isValidSession() {
        return validSession;
    }

    /**
     * @return the workingMode
     */
    public WorkingMode getWorkingMode() {
        return workingMode;
    }

    /**
     * @param workingMode the workingMode to set
     */
    public void setWorkingMode(WorkingMode workingMode) {
        this.workingMode = workingMode;
    }

    public org.jsoup.nodes.Document GetIssueFields(Project project, Issue issue, String token, String action) throws MalformedURLException, IOException, WebClientException
    {
        return webClient.GetNewIssueForm(project, issue, token, action);
    }

    public void GetIssueFileds(Issue issue)
    {

    }
    
    public Feedback saveIssue(Issue issue, String token, File[] files, String[] fileDesc) throws WebClientException
    {
        Feedback fb = null;
        org.jsoup.nodes.Document doc = webClient.SaveNewIssue(issue, token, files, fileDesc);
        Elements els = doc.select("#errorExplanation");
        if( ! els.isEmpty() )
        {
            fb = new Feedback();
            fb.setCaption(els.select("h2").text());
            fb.setHeader(els.select("p").text());
            List<String> errors = new ArrayList<String>();
            for(Element el : els.select("li"))
            {
                errors.add(el.text());
            }
            fb.setMessages(errors);
            fb.setFeedbackType(FeedbackType.VALIDATION_ERROR);
        }
        else
        {
            fb = new Feedback();
            fb.setFeedbackType(FeedbackType.SUBMIT_SUCEES);
            Element el = doc.select("div#content div:eq(0)").get(0);
            fb.setCaption(el.text());
            fb.setHeader(el.text());
        }
        return fb;
    }
    
    public org.jsoup.nodes.Document GetNewLogTime(Issue issue)  throws WebClientException
    {
        return webClient.GetNewLogTime(issue);
    }
}
